package com.ishitong.platform.common.service;


import java.io.Serializable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;

import com.ishitong.platform.common.dao.GenericDao;
import com.ishitong.platform.common.dao.GenericDaoInterface;
import com.ishitong.platform.common.page.Page;


/**
 * 普通的服务类
 * @author liufeng
 *
 */
public abstract class GenericService<SuperClass> implements GenericDaoInterface<SuperClass>
{


	/**
	 * 设置当前服务的Dao
	 * @param genericDao
	 */
	public abstract GenericDao getGenericDao();
	
	
	/**
	 * 通过主键取得实例
	 * 
	 * @param id
	 *            主键
	 * @return 该主键对应的实例
	 */
	public SuperClass get(Serializable id)
	{
		return (SuperClass) getGenericDao().get(id);
	}

	/**
	 * 保存实例
	 * 
	 * @param obj
	 *            待保存的实例
	 */
	public void save(SuperClass obj)
	{
		getGenericDao().save(obj);
	}

	/**
	 * 保存实例
	 * 
	 * @param obj
	 *            待保存的实例
	 */
	public void saveOnly(SuperClass obj)
	{
		getGenericDao().saveOnly(obj);
	}

	/**
	 * 根据主键删除实例
	 * 
	 * @param id
	 *            带删除实例的主键
	 */
	public void remove(Serializable id)
	{
		getGenericDao().remove(id);
	}

	/**
	 * 删除指定的实例
	 * 
	 * @param obj
	 *            待删除的实例
	 */
	public void remove(SuperClass obj)
	{
		getGenericDao().remove(obj);
	}

	/**
	 * 取得和被持久化的EntityClass关联的Criteria实例。
	 * 
	 * @return 持久化类的Criteria对象
	 */
	public Criteria getCriteria()
	{
		return getGenericDao().getCriteria();
	}

	/**
	 * 通过hql查询记录集。<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.findByCriteria(hql, pageSize, pageNum);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, arg0);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, arg0,arg1);
	 * <li> dao.findByCriteria(hql, pageSize, pageNum, new
	 * Object[arg0,arg1,arg2]);
	 * </ul>
	 * pageSize和pageNum必须同时大于0才有效，否则将取出所有符合条件的记录。
	 * 
	 * @param hql
	 *            查询语句
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @param args
	 *            查询语句参数
	 * @return 该页的Page对象
	 * @see com.ishitong.platform.common.page.Page
	 */
	public Page findByHql(String hql, int pageSize, int pageNum, Object... args)
	{
		return getGenericDao().findByHql(hql, pageSize, pageNum, args);
	}

	/**
	 * 统计查询语句的结果集大小。<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.count(hql);
	 * <li> dao.count(hql, arg0);
	 * <li> dao.count(hql, arg0, arg1);
	 * <li> dao.count(hql, new Object[arg0,arg1,arg2]);
	 * </ul>
	 * 
	 * @param hql
	 *            查询语句
	 * @param args
	 *            绑定的参数
	 * @return 结果集的大小
	 */
	public long count(String hql, Object... args)
	{
		return getGenericDao().count(hql, args);
	}

	/**
	 * 分页查询函数，使用Criteria.
	 * 
	 * @param criteria
	 *            查询用Criteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 */
	public Page findByCriteria(Criteria criteria, int pageSize, int pageNum)
	{
		return getGenericDao().findByCriteria(criteria, pageSize, pageNum);
	}

	/**
	 * 取得河北持久化的EntityClass关联的DetachedCriteria。<br>
	 * 此方法供业务层之上的上层代码使用，如Struts的Action类或者JUnit的测试代码。
	 * 
	 * @return 查询对象
	 */
	public DetachedCriteria getDetachedCriteria()
	{
		return getGenericDao().getDetachedCriteria();
	}

	/**
	 * 分页查询函数，使用DetachedCriteria
	 * 
	 * @param dc
	 *            设置好条件的DetachedCriteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 */
	public Page findByDetachedCriteria(DetachedCriteria dc, int pageSize, int pageNum)
	{
		return getGenericDao().findByDetachedCriteria(dc, pageSize, pageNum);
	}

	/**
	 * 判断对象某几列值的组合在数据库中不存在重复记录
	 * 
	 * @param entity
	 *            实例对象
	 * @param names
	 *            在POJO里相对应的属性名的列表
	 * @return true: 有重复记录，flase: 无重复记录
	 */
	public boolean isNotUnique(Object entity, String... names)
	{
		return getGenericDao().isNotUnique(entity, names);
	}

	/**
	 * 消除与 Hibernate Session 的关联
	 * 
	 * @param obj
	 *            待操作的实例
	 */
	public void evit(SuperClass obj)
	{
		getGenericDao().evit(obj);
	}

	/**
	 * 分页取得所有记录
	 * 
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            待取得页码，从1开始
	 * @param orderBy
	 *            排序字段
	 * @param isAsc
	 *            是否升序，false表示降序
	 * @return 指定页码的记录
	 */
	public Page listAll(int pageSize, int pageNum, String orderBy, boolean isAsc)
	{
		return getGenericDao().listAll(pageSize, pageNum, orderBy, isAsc);
	}

	/**
	 * 分页查询指定字段的值等于指定值的记录
	 * 
	 * @param fieldName
	 *            字段名称
	 * @param value
	 *            指定的值
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页号，从1开始
	 * @return 指定页的记录
	 */
	public Page findByFieldEquals(String fieldName, Object value, int pageSize, int pageNum)
	{
		return getGenericDao().findByFieldEquals(fieldName, value, pageSize, pageNum);
	}

	/**
	 * 通过hql查询记录集。<br>
	 * 此方法不同于findByHQL之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 此方法含有可变参数args，可用如下四种方法调用：
	 * <ul>
	 * <li>dao.findByHql(hql, pageSize, pageNum);
	 * <li> dao.findByHql(hql, pageSize, pageNum, arg0);
	 * <li> dao.findByHql(hql, pageSize, pageNum, arg0, arg1);
	 * <li> dao.findByHql(hql, pageSize, pageNum, new Object[arg0, arg1, arg2]);
	 * </ul>
	 * pageSize和pageNum必须同时大于0才有效，否则将取出所有符合条件的记录。
	 * 
	 * @param hql
	 *            查询语句
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @param args
	 *            查询语句参数
	 * @return 该页的Page对象
	 * @see com.ishitong.platform.common.dao.GenericDao#findByHql(String, int,
	 *      int, Object[])
	 */
	public List findFastByHql(String hql,  Object... args)
	{
		return getGenericDao().findFastByHql(hql, args);
	}

	/**
	 * 分页查询函数，使用Criteria.<br>
	 * 此方法不同于findByCriteria之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 
	 * @param criteria
	 *            查询用Criteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 * @see com.ishitong.platform.common.dao.GenericDao#findByCriteria(org.hibernate.Criteria,
	 *      int, int)
	 */
	public List findFastByCriteria(Criteria criteria)
	{
		return getGenericDao().findFastByCriteria(criteria);
	}

	/**
	 * 分页查询函数，使用DetachedCriteria<br>
	 * 此方法不同于findByDetachedCriteria之处在于调用此方法后，本方法不做count操作，本方法只返回包含结果集的List对象，而不返回Page对象<br>
	 * 
	 * @param dc
	 *            设置好条件的DetachedCriteria
	 * @param pageSize
	 *            每页的记录数
	 * @param pageNum
	 *            页码，从1开始
	 * @return 指定页码的记录
	 * @see com.ishitong.platform.common.dao.GenericDao#findByDetachedCriteria(org.hibernate.criterion.DetachedCriteria,
	 *      int, int)
	 */
	public List findFastByDetachedCriteria(DetachedCriteria dc)
	{
		return getGenericDao().findFastByDetachedCriteria(dc);
	}

	/**
	 * 查询分页数据
	 * 
	 * @param pageSize
	 * @param pageNum
	 * @return
	 */
	public Page find(int pageSize, int pageNum)
	{
		return getGenericDao().find(pageSize, pageNum);
	}

	/**
	 * 根据唯一字段值ID查询数据
	 * 
	 * @param id
	 * @return
	 */
	public SuperClass findByUniqueKey(String fieldName, Object value)
	{
		return (SuperClass)getGenericDao().findByUniqueKey(fieldName, value);
	}

	/**
	 * 通过主键ID查询数据
	 * 
	 * @param value
	 * @return
	 */
	public SuperClass findByPrimaryKey(Object value)
	{
		return (SuperClass)getGenericDao().findByPrimaryKey(value);
	}

	/**
	 * 执行HQL,返回记录受影响的行数
	 * 
	 * @param hql
	 * @param args
	 * @return
	 */
	public int executeByHql(String hql, Object... args)
	{
		return getGenericDao().executeByHql(hql, args);
	}

	/**
	 * 刷新当前session
	 */
	public void flushSession()
	{
		getGenericDao().flushSession(); 
	}
	
	
	/** ******************************直接通过SQL执行接口******************************************** */
	/**
	 * 通过普通SQL语句进行查询
	 * 
	 * @param sql
	 * @param pageSize
	 * @param pageNum
	 * @param args
	 * @return
	 */
	public Page findBySql(String sql, int pageSize, int pageNum, Object... args)
	{
		return getGenericDao().findBySql(sql, pageSize, pageNum, args);
	}

	/**
	 * 通过普通SQL语句进行查询
	 * 
	 * @param sql
	 * @param pageSize
	 * @param pageNum
	 * @param args
	 * @return
	 */
	public List findFastBySql(String sql,  Object... args)
	{
		return getGenericDao().findFastBySql(sql,  args);
	}

	/**
	 * 执行SQL,并返回影响的记录数
	 * 
	 * @param sql
	 * @param args
	 */
	public int executeBySql(String sql, Object... args)
	{
		return getGenericDao().executeBySql(sql, args);
	}

	/**
	 * 获得记录总数,通过普通SQL
	 * 
	 * @param sql
	 * @param args
	 * @return
	 */
	public long countBySql(String sql, Object... args)
	{
		return getGenericDao().countBySql(sql, args);
	}


	/** ******************************直接通过SQL执行接口******************************************** */

	/**
	 * ******************************直接通过SQL执行，返回对象
	 * 接口********************************************
	 */
	/**
	 * 通过普通SQL语句进行查询 通过字段关联,构造entity对象
	 * 
	 * @param sql
	 * @param pageSize
	 * @param pageNum
	 * @param args
	 * @param fieldAlign
	 * @param entity
	 * @return
	 */
	public List findFastBySql(String sql,  Class metaObject, Object... args)
	{
		return getGenericDao().findFastBySql(sql, metaObject, args);
	}

	/**
	 * 通过普通SQL语句进行查询 通过字段关联,构造entity对象
	 * 
	 * @param sql
	 * @param pageSize
	 * @param pageNum
	 * @param args
	 * @param fieldAlign
	 * @param entity
	 * @return
	 */
	public Page findBySql(String sql, int pageSize, int pageNum, Class metaObject, Object... args)
	{
		return getGenericDao().findBySql(sql, pageSize, pageNum, metaObject, args);
	}

	/**
	 * 查询单条记录
	 * 
	 * @param sql
	 * @param pageSize
	 * @param pageNum
	 * @param metaObject
	 * @param args
	 * @return
	 */
	public Object findOneBySql(String sql, Class metaObject, Object... args)
	{
		return getGenericDao().findOneBySql(sql, metaObject, args);
	}


	/**
	 * ******************************直接通过SQL执行，返回对象
	 * 接口********************************************
	 */

	/** **********************增加FreeSql Dao操作********************************* */
	/***************************************************************************
	 * 通过FreeSQL查询批定页数据,返回List
	 * 
	 * @param name
	 *            freeSQL名称
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码
	 * @param parameterObject
	 *            查询条件对象
	 * @return List
	 */
	public List findFastByFreeSql(String name,  Object parameterObject)
	{
		return getGenericDao().findFastByFreeSql(name,  parameterObject);
	}

	/***************************************************************************
	 * 通过FreeSQL查询批定页数据
	 * 
	 * @param name
	 *            freeSQL名称
	 * @param pageSize
	 *            每页记录数
	 * @param pageNum
	 *            页码
	 * @param parameterObject
	 *            查询条件对象
	 * @return Page
	 */
	public Page findByFreeSql(String name, int pageSize, int pageNum, Object parameterObject)
	{
		return getGenericDao().findByFreeSql(name, pageSize, pageNum, parameterObject);
	}

	/**
	 * 查询单行数据
	 * 
	 * @param name
	 * @param parameterObject
	 * @return
	 */
	public Object findOneByFreeSql(String name, Object parameterObject)
	{
		return getGenericDao().findOneByFreeSql(name, parameterObject);
	}

	/***************************************************************************
	 * 通过FreeSQL查询总记录数
	 * 
	 * @param name
	 *            freeSQL名称
	 * @param parameterObject
	 *            查询条件对象
	 * @return long
	 */
	public long countByFreeSql(String name, Object parameterObject)
	{
		return getGenericDao().countByFreeSql(name, parameterObject);
	}


	/***************************************************************************
	 * 通过FreeSQL 执行SQL
	 * 
	 * @param name
	 *            freeSQL名称
	 * @param parameterObject
	 *            查询条件对象
	 * @return long
	 */
	public long executeByFreeSql(String name, Object parameterObject)
	{
		return getGenericDao().executeByFreeSql(name, parameterObject);
	}

	/** **********************增加FreeSql Dao操作********************************* */

	public Connection getConnection()
	{
		return getGenericDao().getConnection();
	}
	
	
	/**
	 * 存储过程执行
	 * @param sql 存储过程名称 { ?=call qktq(?,?,?)}
	 * @param Map<Integer,Integer> 输出参数  key为输出下标，value 为输出类型java.sql.Types 中的类型值
	 * @param resultParamIndex 返回结果下标值，从1开始
	 * @param args 存储过程输入参数
	 * @return Map<Integer,Object>  key为下标 value为值
	 */
	public Map<Integer,Object> execProdure(String sql,Map<Integer,Integer> outParam,Object ...args)
	{
		return getGenericDao().execProdure(sql, outParam, args);
	}
}
